package com.woniuxy.service.impl;

import com.woniuxy.Mapper.AppointmentMapper;
import com.woniuxy.Mapper.OrderMapper;
import com.woniuxy.client.OrderServiceFeignClient;
import com.woniuxy.entity.Appointments;
import com.woniuxy.entity.ShopOrders;
import com.woniuxy.service.AppointmentService;
import com.woniuxy.service.EmailService;
import com.woniuxy.utils.ResponseResult;
import com.woniuxy.vo.AppointmentsVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class AppointmentServiceImpl implements AppointmentService {
    @Autowired
    OrderMapper orderMapper;
    @Autowired
    EmailService emailService;
    //注入redis
    private final RedisTemplate<String, Object> redisTemplate;
    private final OrderServiceFeignClient orderServiceFeignClient;
    private final AppointmentMapper appointmentMapper;
    private final RestTemplate restTemplate;

    // 构造器注入
    @Autowired
    public AppointmentServiceImpl(
            RedisTemplate<String, Object> redisTemplate,
            OrderServiceFeignClient orderServiceFeignClient,
            AppointmentMapper appointmentMapper,
            RestTemplate restTemplate) {
        this.redisTemplate = redisTemplate;
        this.orderServiceFeignClient = orderServiceFeignClient;
        this.appointmentMapper = appointmentMapper;
        this.restTemplate = restTemplate;
    }
    @Override
    public Object buildAppointment(AppointmentsVo appointments) {
        // 先判断redis里是否有该字段  如果没有该字段则生成订单 如果有该字段则返回提示 不可以重复下单
        System.out.println(appointments+"预约的参数");
        // 设置结构化的Redis key，包含订单号便于后续处理

//        String rediskey= appointments.getUserId()+appointments.getDate()+appointments.getTimeSolt();
//        if(redisTemplate.hasKey(rediskey)){
//            System.out.println("rediskey---"+rediskey);
//            return  "不可以购买同一时段1";
//        }else{
            AppointmentsVo appointmentsVo = new AppointmentsVo();
            appointmentsVo.setUserId(appointments.getUserId());
            appointmentsVo.setDate(appointments.getDate());
            appointmentsVo.setTimeSolt(appointments.getTimeSolt());
            appointmentsVo.setStatus(1);
            List<AppointmentsVo> appointmentsVos = appointmentMapper.selectByOrderCon(appointmentsVo);
            System.out.println(appointmentsVo+"查询数据库"+appointmentsVos);
            if(appointmentsVos.size()>0){
                System.out.println("appointmentsVos---"+appointmentsVos);
                return  "不可以购买同一时段2";
            }
            ShopOrders shopOrders=new ShopOrders(null,null,appointments.getUserId(),appointments.getTotalAmount(),appointments.getPaymentAmount(),
                    appointments.getStatus(),1,null,null,null,"1",appointments.getIdCard());
            // 生成订单
            ResponseResult<ShopOrders> shopOrdersResponseResult = orderServiceFeignClient.insertOrderMedical(shopOrders);
            ShopOrders shoporders = shopOrdersResponseResult.getData();
            System.out.println("检查这里的"+shoporders.getOrderNumber()+"---"+shoporders);
            // 同时生成预约信息
            Appointments appointments1 = new Appointments(null,appointments.getPatientName(),appointments.getPatientPhone(),appointments.getScheduleId(),"待确认",appointments.getCreateTime(),appointments.getNotes(),appointments.getIdCard(),appointments.getDate(),appointments.getTimeSolt(),appointments.getUserId(),shoporders.getOrderNumber());
            appointmentMapper.buildAppointment(appointments1);

            int i=appointmentMapper.updateAppointmentCounts(appointments.getScheduleId());
            System.out.println("修改排班表的信息"+i+ "appointmentsVo.getScheduleId()"+appointments.getScheduleId());
            String rediskey = String.format("appointment:unpaid,%s,%s,%s,%s",
                appointments.getUserId(),
                appointments.getDate(),
                appointments.getTimeSolt(),
                shoporders.getOrderNumber()
                );
        System.out.println("测试+新的rediskey"+rediskey);
            // 设置30分钟过期时间
//            redisTemplate.opsForValue().set(rediskey, "1", 30, TimeUnit.MINUTES);
            redisTemplate.opsForValue().set(rediskey, shoporders.getOrderNumber(),60, TimeUnit.SECONDS);

            return  shoporders;
//        }
    }

    @Override //
    public List<AppointmentsVo> selectAppByOrCond(Integer userId, Integer status, Integer payType) {
        List<AppointmentsVo> appointmentsVos = appointmentMapper.selectByOrderConditions(userId, status, Integer.valueOf(String.valueOf(payType)));
        System.out.println("----------"+appointmentsVos);
        return appointmentsVos;
    }
    public boolean updateAppStatusByConditions(Long userId, String date, String timeSolt) {
        int affectedRows = appointmentMapper.updateAppStatusByConditions(
                userId,
                timeSolt,
                date,
                "已确认"  // 新状态值（需符合数据库 enum 类型：'待确认','已确认','已取消','已完成'）
        );
        return affectedRows > 0;
    }

    @Override
    public boolean updateStatusToPaid( Long order_number,Integer newStatus) {
        int affectedRows = appointmentMapper.updateStatusToPaid( order_number,newStatus);
        return affectedRows > 0; // 受影响行数>0表示更新成功
    }

    @Override
    public boolean updateAppStatusByConditions(Long userId, String timeSolt, String date, String newAppStatus) {
        int affectedRows = appointmentMapper.updateAppStatusByConditions(userId,timeSolt,date,newAppStatus);
        return affectedRows > 0; // 受影响行数>0表示更新成功
    }



    /**
     * 减少可预约数并增加当前预约数（例如用户成功预约后调用）
     * @param scheduleId 排班ID
     * @return 是否更新成功
     */
    public boolean updateAppointmentCounts(Long scheduleId) {
        int affectedRows = appointmentMapper.updateAppointmentCounts(scheduleId);
        return affectedRows > 0; // 受影响行数>0表示更新成功
    }
    @Override
    public void notifyUrl(Map<String, String> params) {
        // 这里处理支付成功的业务逻辑
        // 必须返回success表示成功接收通知
        // 修改订单的状态 通过userid status=1 timeSolt date 查找到数据并且修改  status 改成 2
        System.out.println("回调的参数"+params);
        String body = params.get("body");

        Map<String, String> convertparams = convert(body);
        emailService.sendToQQEmail("1285161740@qq.com", "智慧养老院", "尊敬的用户,您于"+convertparams.get("timeSolt")+" "+convertparams.get("date")+"预约的的门诊,已支付成功");
        appointmentMapper.updateAppStatusByConditions(Long.valueOf(convertparams.get("userId")),convertparams.get("timeSolt"),convertparams.get("date"),"已确认");
        orderMapper.updateOrderStatus(Long.valueOf(convertparams.get("TradeNo")), 2);
//        appointmentMapper.updateStatusToPaid( Long.valueOf(convertparams.get("TradeNo")),2);
        //修改预约订单的状态 通过userid app_status=待确认 timeSolt date 查找到数据并且修改


    }

    @Override
    public List<AppointmentsVo> findAppointmentsByConditions( String payType,Integer status,Long userId) {
        return appointmentMapper.findAppointmentsByConditions(payType,status,userId);
    }

    // 定义字段名顺序（必须与逗号分隔字符串中的值顺序一一对应！）
    private static final String[] FIELD_NAMES = {
            "TradeNo","totalAmount","subject",
            "scheduleId", "patientId", "doctorId", "appointmentDate",
            "paymentAmount", "timeSolt", "userId",
            "payType", "paymentType", "status", "patientName",
            "idCard", "date","appointmenturl","notify"
    };

    /**
     * 将逗号分隔字符串转换为Map<String, String>（所有值按字符串处理）
     * @param csvString 逗号分隔的字符串（格式需与FIELD_NAMES顺序一致）
     * @return 包含字段名-字符串值的Map
     * @throws IllegalArgumentException 当输入异常时抛出
     */
    public static Map<String, String> convert(String csvString) {
        // 1. 校验输入非空
        if (csvString == null || csvString.trim().isEmpty()) {
            throw new IllegalArgumentException("输入字符串不能为空");
        }

        // 2. 分割字符串为值数组（按逗号分割）
        String[] values = csvString.split(",", -1); // -1：保留空值（如连续逗号的场景）
        System.out.println("---------------csvString--------------"+csvString);
        // 3. 校验字段数量（值数组长度必须与字段名数组长度一致）
        if (values.length != FIELD_NAMES.length) {
            throw new IllegalArgumentException(
                    String.format("字段数量不匹配：期望%d个，实际%d个", FIELD_NAMES.length, values.length)
            );
        }

        // 4. 映射字段名和值到Map（所有值直接作为字符串存储）
        Map<String, String> resultMap = new HashMap<>(FIELD_NAMES.length);
        for (int i = 0; i < FIELD_NAMES.length; i++) {
            String fieldName = FIELD_NAMES[i];
            String value = values[i]; // 不做类型转换，直接存原始字符串
            resultMap.put(fieldName, value);
        }

        return resultMap;
    }


}
